package com.bupt.utils;

import com.bupt.annotation.MParam;
import com.bupt.constants.MimeTypeEnum;
import com.bupt.constants.ResponseResult;
import com.bupt.exception.BaseException;
import com.bupt.utils.excel.ExcelUtils;
import com.google.gson.Gson;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

public abstract class ExploreWriteUtils {

    private static final int ALLOCATION_SIZE = 10240;

    // 将信息写会浏览器
    // json 数据的形式
    public static void writeMessage(@MParam("code") ResponseResult.RetCodeConstant retCodeConstant,
                                    @MParam("请求对象") HttpServletRequest request,
                                    @MParam("响应对象") HttpServletResponse response,
                                    @MParam("数据对象") Object message) throws IOException {
        // 设置一些对象头信息
        ISetHeader.preSetCommonHeader(request, response);
        // 设置返回的数据类型是 json
        response.setContentType(MimeTypeEnum.APPLICATION_JSON.getMimeType());
        Gson gson = new Gson();
        ResponseResult<?> responseResult = ResponseResult.createResult(retCodeConstant, "操作失败", message);
        // json 化
        String writeMessage = gson.toJson(responseResult);
        String callbackFunName = request.getParameter("callback");
        PrintWriter writer = response.getWriter();
        // 判断是都属于jsonp的请求方式 按照不同的方式 进行返回
        if (callbackFunName == null || callbackFunName.equalsIgnoreCase("")) {
            writer.println(writeMessage);
        } else {
            writer.println(callbackFunName + "( " + writeMessage + " )");
        }
        // 设置返回吗
        response.setStatus(HttpServletResponse.SC_OK);
        writer.close();
        // 方式执行其他的方法
        return;
    }


    // 下载文件的操作
    public static void downLoadFile(HttpServletRequest request, HttpServletResponse response, InputStream inputStream,
                                    String downFileName) throws IOException, BaseException {
        if (null == inputStream) throw new BaseException("输入流不能为空");
        ISetHeader.preSetCommonHeader(request, response);
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(downFileName, "UTF-8"));
        OutputStream out = null;
        try {
            int len = -1;
            byte[] buffer = new byte[ALLOCATION_SIZE];
            out = response.getOutputStream();
            while ((len = inputStream.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        } finally {
            // 关闭流操作
            if (out != null) {
                out.flush();
                out.close();
            }
            inputStream.close();
        }
    }

    // 下载文件的操作
    public static void downLoadFileByBytes(HttpServletRequest request, HttpServletResponse response, byte[] bytes,
                                           String downFileName) throws IOException, BaseException {
        if (null == bytes || bytes.length == 0) throw new BaseException("输入流不能为空");
        ISetHeader.preSetCommonHeader(request, response);
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(downFileName, "UTF-8"));
        OutputStream out = null;
        try {
            out = response.getOutputStream();
            out.write(bytes, 0, bytes.length);
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        } finally {
            if (out != null) {
                out.flush();
                out.close();
            }
        }
    }

    // 下载文件的操作
    public static void downLoadFile(HttpServletRequest request, HttpServletResponse response, String fileAbsolutePath,
                                    String downFileName) throws IOException, BaseException {
        LocalVerify.verifyString(fileAbsolutePath, "fileAbsolutePath");
        LocalVerify.verifyString(downFileName, "downFileName");
        ISetHeader.preSetCommonHeader(request, response);
        OutputStream out = null;
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(fileAbsolutePath);
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(downFileName, "UTF-8"));
            int len = -1;
            byte[] buffer = new byte[ALLOCATION_SIZE];
            out = response.getOutputStream();
            while ((len = inputStream.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        } finally {
            if (out != null) {
                out.flush();
                out.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        }
    }

    // 下载 excel
    public static <T> void downLoadExcelByCurrentData(HttpServletRequest request, HttpServletResponse response, List<T> data,
                                                      String downFileName, String sheetName) throws IOException, BaseException {
        downLoadExcelByCurrentData(request, response, data, downFileName, sheetName, false);
    }

    // 下载 excel
    public static <T> void downLoadExcelByCurrentData(HttpServletRequest request, HttpServletResponse response, List<T> data,
                                                      String downFileName, String sheetName,
                                                      @MParam("是否下载模版") boolean isMould) throws IOException, BaseException {
        if (null == data || data.size() == 0) throw new BaseException("下载的数据不能是空");
        if (null == sheetName || "".equals(sheetName)) throw new BaseException("sheetName is empty");
        ISetHeader.preSetCommonHeader(request, response);
        OutputStream out = null;
        try {
            out = response.getOutputStream();
            HSSFWorkbook hssfWorkbook = ExcelUtils.getHSSFWorkbook(sheetName, data, isMould);
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(downFileName + ".xls", "UTF-8"));
            hssfWorkbook.write(out);
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        } finally {
            if (out != null) {
                out.flush();
                out.close();
            }
        }
    }

    // 下载 excel 多页的操作
    public static <T> void downLoadExcelByCurrentData(HttpServletRequest request, HttpServletResponse response,
                                                      Map<String, List<T>> dataMapVal,
                                                      String downFileName) throws IOException, BaseException {
        // 下载数据的操作
        downLoadExcelByCurrentData(request, response, dataMapVal, downFileName, false);
    }

    // 下载 excel 多页的操作
    public static <T> void downLoadExcelByCurrentData(HttpServletRequest request, HttpServletResponse response,
                                                      Map<String, List<T>> dataMapVal,
                                                      String downFileName, @MParam("是否下载模版") boolean isMould) throws IOException, BaseException {
        if (null == dataMapVal || dataMapVal.size() == 0) throw new BaseException("下载的数据不能是空");
        ISetHeader.preSetCommonHeader(request, response);
        OutputStream out = null;
        try {
            out = response.getOutputStream();
            HSSFWorkbook hssfWorkbook = ExcelUtils.getHSSFWorkbook(dataMapVal, isMould);
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(downFileName + ".xls", "UTF-8"));
            hssfWorkbook.write(out);
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        } finally {
            if (out != null) {
                out.flush();
                out.close();
            }
        }
    }
}
